﻿using System;
using System.Collections;
using KnightWeapons;
using Unity.Netcode;
using UnityEngine;

public class Bullet : NetworkBehaviour
{    
    [SerializeField] LayerMask targetLayer;
    [SerializeField] BulletData bulletData;
    Rigidbody2D rigidBody2d;
    public NetworkVariable<int> PredictBulletIdx;
    
    private void Awake()
    {        
        rigidBody2d = GetComponent<Rigidbody2D>();
        PredictBulletIdx = new();
    }

    public override void OnNetworkSpawn()
    {
        if (IsOwner)
        {
            var weaponManager = WeaponManager.Instance;
            if (weaponManager.PredictBullets.TryGetValue(PredictBulletIdx.Value, out Bullet bullet))
            {
                weaponManager.PredictBullets.Remove(PredictBulletIdx.Value);
                StartCoroutine(SmoothCorrect(transform, bullet.transform.position, 0.008f));
                Destroy(bullet.gameObject);                
            }
            Fire();
        }
    }

    IEnumerator SmoothCorrect(Transform bullet, Vector3 target, float duration)
    {
        Vector3 start = bullet.position;
        float t = 0;
        while (t < 1)
        {
            t += Time.deltaTime / duration;
            bullet.position = Vector3.Lerp(start, target, t);
            yield return null;
        }
    }

    public void Fire()
    {        
        rigidBody2d.velocity = transform.rotation * Vector2.right * bulletData.Speed;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (!IsOwner)
            return;
        if((1<<collision.gameObject.layer & targetLayer)!=0)
        {
            if(collision.TryGetComponent<Slime>(out var slime))
            {
                slime.OnHit(bulletData.Damage,OwnerClientId);
            }
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if(!IsOwner)
            return;
        if (collision.gameObject.layer == LayerMask.NameToLayer("Background") && IsSpawned)
        {            
            StartCoroutine(DespawnCoroutine());
        }
    }    
    
    IEnumerator DespawnCoroutine()
    {
        yield return new WaitForSeconds(2f);
        DespawnRpc();
    }

    [Rpc(SendTo.Server)]
    void DespawnRpc()
    {
        if (IsSpawned)
            NetworkObject.Despawn();
    }
}
